/* mot83xxPci.c - Motorola ads 83xx PCI Bridge functions */

/* Copyright 1984-2005 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------
01a,04feb05,dtr  File created from mot85xxPci.c.
*/

/* PCI Host Bridge setup File */

#include "vxWorks.h"
#include "config.h"
#include "sysLib.h"

#include "drv/pci/pciConfigLib.h" 	
#include "drv/pci/pciIntLib.h" 	
#include "drv/pci/pciAutoConfigLib.h"	
#include "sysBusPci.h"
#include "mot83xxPci.h"

#define MAX_NUM_VECTORS 4

UINT32 pciRegRead(UINT32 *adrs);
void   pciRegWrite(UINT32 *adrs,UINT32 value);

void pciConfigTest();
#define PCI_REG_READ  pciRegRead
#define PCI_REG_WRITE  pciRegWrite


/*************************************************************************
 * 
 * mot83xxBridgeInit - This function performs all the initialisation 
 * required for the Bridge/Interrupts/PCI Bus to function. It does some
 * low level processor initialisation which might normally be done in 
 * romInit as it is optional to do use this and shows what the core 
 * changes required to bring up the bridge.
 * 
 * RETURNS : NONE
 *
 */


void mot83xxBridgeInit()
    {
      STATUS result;

      /* Initialise LAWBAR/LAWAR for PCI */
      *PCI1_GCR(CCSBAR) = 0x1; /* Clear  PCI reset */

      {
      volatile int i ;
      for(i = 0 ; i < 0x80000 ; i++) ;
      }

      *PCI1_GCR(CCSBAR) = 0x0; /* Put PCI reset */

      {
      volatile int i ;
      for(i = 0 ; i < 0x80000 ; i++) ;
      }

      *M83XX_PCILAWBARn(CCSBAR,0) = CPU_PCI_MEM_ADRS ;
      *M83XX_PCILAWARn(CCSBAR,0) = LAWAR_ENABLE  | LAWAR_SIZE_256MB;

      *M83XX_PCILAWBARn(CCSBAR,1) = CPU_PCI_MEMIO_ADRS ;
      *M83XX_PCILAWARn(CCSBAR,1) = LAWAR_ENABLE  | LAWAR_SIZE_256MB;

      *PCI1_ECR(CCSBAR) = 0x0; /* Generate interrupt if PCI error and ESR set*/
      *PCI1_ESR(CCSBAR) = 0xffffffff; /* Clear status */

      *PCI1_GCR(CCSBAR) = 0x1; /* Clear PCI reset */


      /* May need to handle target abort */
      
      /* Set outbound translation window adresses */
   
      result = sysPciConfigWrite(0,0,0,
				 PCI_CFG_BASE_ADDRESS_0,
				 0x4,
				 PCI_BRIDGE_PIMMR_BASE_ADRS);


      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_BASE_ADRS_REGn(CCSBAR,0)),
		    CPU_PCI_MEM_ADRS >> 12);

      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_TRANS_ADRS_REGn(CCSBAR,0)),
		    PCI_MEM_ADRS >> 12);

      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_BASE_ADRS_REGn(CCSBAR,0)),
		    CPU_PCI_MEMIO_ADRS >> 12);

      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_TRANS_ADRS_REGn(CCSBAR,0)),
		    PCI_MEMIO_ADRS >> 12);

      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_ATTR_REGn(CCSBAR,2)),
		    0);

      /* Switch on the outbound trnslation windows */
      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_ATTR_REGn(CCSBAR,0)),
		    0xa00f0000); /* Enable|Prefetchable|256MB */

      PCI_REG_WRITE((UINT32*)(PCI_OUTBOUND_ATTR_REGn(CCSBAR,1)),
		    0xa00f0000); /* Enable|Prefetchable|256MB */

      PCI_REG_WRITE((UINT32*)(PCI1_INBOUND_BASE_ADRS_REGn(CCSBAR,1)),
		    0);

      PCI_REG_WRITE((UINT32*)(PCI1_INBOUND_TRANS_ADRS_REGn(CCSBAR,1)),
		    0);
			  
      PCI_REG_WRITE((UINT32*)(PCI1_INBOUND_ATTR_REGn(CCSBAR,1)),
		    PCI_WINDOW_ENABLE_BIT | 
		    PCI_IN_ATTR_RTT_LM_WRITE_SNOOP | 
		    PCI_IN_ATTR_RTT_LM_READ_SNOOP | 
		    PCI_ATTR_WS_256M);

      PCI_REG_WRITE((UINT32*)(PCI1_INBOUND_ATTR_REGn(CCSBAR,2)),
		    0x0);
      PCI_REG_WRITE((UINT32*)(PCI1_INBOUND_ATTR_REGn(CCSBAR,3)),
		    0x0);

      
      /* configure the bridge as bus master */

      result = sysPciConfigWrite(0,0,0,
				 COMMAND_REGISTER_OFFSET,
				 COMMAND_REGISTER_WIDTH,
				 PCI_CMD_IO_ENABLE |
				 PCI_CMD_MEM_ENABLE | 
				 PCI_CMD_MASTER_ENABLE);

    }


void pciRegWrite(UINT32 *adrs,UINT32 value)
    {
    *adrs = value;
    WRS_ASM("isync;sync");
    }

UINT32 pciRegRead(UINT32 *adrs)
    {
    return (*adrs);
    }

void pciConfigTest()
    {
    int loop;
    UINT32 var;

    for(loop=0;loop<0x40;loop+=4)
        {
        sysPciConfigRead(0,0,0,loop,0x4,&var);
        printf("Word %d Value %x\n",loop,var);
        }
    }

